package org.mspring.mlog.service;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.mspring.mlog.dao.AttachmentDao;
import org.mspring.mlog.entity.Attachment;
import org.mspring.mlog.service.exception.StorageException;
import org.mspring.mlog.utils.AttachmentUtils;
import org.mspring.platform.security.SecurityUtils;
import org.mspring.platform.security.entity.User;
import org.mspring.platform.security.exception.UNLoginException;
import org.mspring.platform.utils.ImageUtils;
import org.mspring.platform.utils.Size;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 *
 * @author Gao Youbo
 * @since 2013-06-18 16:34:42
 */
@Service
public class AttachmentService {

    private static final Logger log = LoggerFactory.getLogger(AttachmentService.class);

    @Autowired
    private StorageService storageService;
    @Autowired
    private AttachmentDao attachmentDao;

    public Attachment findById(long id) {
        return attachmentDao.findById(id);
    }

    /**
     * 查找文章对应的附件
     *
     * @param post
     *            文章编号
     * @return
     */
    public List<Attachment> findAttachmentsByPost(Long post) {
        return findAttachmentsByFid(Attachment.AttachFrom.FROM_POST, post);
    }

    /**
     * 查找twitter对应的附件
     *
     * @param twitter
     *            twitter编号
     * @return
     */
    public List<Attachment> findAttachmentsByTwitter(Long twitter) {
        return findAttachmentsByFid(Attachment.AttachFrom.FROM_TWITTER, twitter);
    }

    /**
     * 根据附件来源编号查找该附件来源对应的附件
     *
     * @param foreignType
     *            附件来源
     * @param foreignKey
     *            附件来源编号
     *
     * @return
     */
    public List<Attachment> findAttachmentsByFid(String foreignType, long foreignKey) {
        return attachmentDao.listByForeign(foreignType, foreignKey);
    }

    /**
     * 创建附件
     *
     * @param mf
     *            附件文件
     * @param from
     *            附件来源
     * @return
     * @throws IOException
     * @throws StorageException
     */
    @Transactional
    public long createAttachment(MultipartFile mf, String from) throws StorageException, IOException, UNLoginException {
        return createAttachment(mf, from, null);
    }

    /**
     * 创建附件
     *
     * @param mf
     *            附件文件
     * @param foreignType
     *            附件来源
     * @param foreignKey
     *            附件来源编号
     * @return
     * @throws IOException
     * @throws StorageException
     * @throws org.mspring.platform.security.exception.UNLoginException
     */
    @Transactional
    public long createAttachment(MultipartFile mf, String foreignType, Long foreignKey) throws StorageException, IOException, UNLoginException {
        User user = SecurityUtils.getCurrentUser();
        if (user == null) {
            throw new UNLoginException();
        }
        String url = "";
        try {
            String fileName = AttachmentUtils.getUploadPath(mf);
            url = storageService.put(fileName, mf.getInputStream());
        } catch (IOException e) {
            log.error("upload file error, " + e.getMessage());
        }
        Attachment attachment = new Attachment();
        attachment.setPath(url);
        attachment.setSize(mf.getSize());
        attachment.setUploadTime(new Date());
        attachment.setUser(user.getId());
        attachment.setForeignType(foreignType);
        attachment.setForeignKey(foreignKey);

        // 判断是否为图片
        String ext = FilenameUtils.getExtension(mf.getOriginalFilename());
        if (ImageUtils.isImage(ext)) {
            attachment.setIsImage(true);
            Size size = ImageUtils.getImageSize(mf.getInputStream());
            attachment.setImageWidth(size.getWidth());
            attachment.setImageHeight(size.getHeight());
        }
        return attachmentDao.create(attachment);
    }

    /**
     * 创建附件
     *
     * @param is
     * @param extension
     * @param user
     * @param foreignType
     * @param foreignKey
     * @return
     * @throws IOException
     * @throws StorageException
     */
    @Transactional
    public long createAttachment(InputStream is, String extension, Long user, String foreignType, Long foreignKey) throws IOException, StorageException {
        if (!ImageUtils.isImage(extension)) {
            extension = "jpg";
        }
        String filename = AttachmentUtils.getUploadPath(extension);
        String src = storageService.put(filename, is);

        Attachment attachment = new Attachment();
        attachment.setPath(src);
        // attachment.setSize(FileUtils.sizeOf(file));
        attachment.setUploadTime(new Date());
        attachment.setUser(user);
        attachment.setForeignType(foreignType);
        attachment.setForeignKey(foreignKey);

        // 判断是否为图片
        if (ImageUtils.isImage(extension)) {
            attachment.setIsImage(true);
            Size size = ImageUtils.getImageSize(is);
            attachment.setImageWidth(size.getWidth());
            attachment.setImageHeight(size.getHeight());
        }
        return attachmentDao.create(attachment);
    }

    /**
     * 删除附件
     *
     * @param id
     */
    @Transactional
    public void deleteAttachment(long id) {
        Attachment attachment = findById(id);
        storageService.remove(attachment.getPath());
        attachmentDao.delete(id);
    }

    /**
     * 设置附件来源
     *
     * @param id
     *            附件编号
     * @param foreignType
     *            附件来源
     * @param foreignKey
     *            附件来源编号
     */
    @Transactional
    public void setAttachmentFid(Long id, String foreignType, Long foreignKey) {
        Attachment attachment = findById(id);
        if (attachment == null) {
            return;
        }
        attachment.setForeignType(foreignType);
        attachment.setForeignKey(foreignKey);
        attachmentDao.update(attachment);
    }

    /**
     * 删除附件
     *
     * @param fid
     * @param from
     */
    @Transactional
    public void deleteAttachment(String foreignType, Long foreignKey) {
        List<Attachment> attachments = findAttachmentsByFid(foreignType, foreignKey);
        if (attachments != null && attachments.size() > 0) {
            for (Attachment attachment : attachments) {
                storageService.remove(attachment.getPath());
            }
        }
        attachmentDao.deleteByForeign(foreignType, foreignKey);
    }

}
